package com.serviceprovider.business.module.sp.payee.controller;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.role.model.Role;
import com.serviceprovider.business.module.admin.role.services.dao.interfaces.IRoleService;
import com.serviceprovider.business.module.admin.user.model.OldUser;
import com.serviceprovider.business.module.admin.user.model.UserProfile;
import com.serviceprovider.business.module.admin.user.services.dao.interfaces.IProfileService;
import com.serviceprovider.business.module.admin.user.services.dao.interfaces.IUserService;
import com.serviceprovider.business.module.sp.payee.model.Payee;
import com.serviceprovider.business.module.sp.payee.model.PayeeProfile;
import com.serviceprovider.business.module.sp.payee.services.dao.interfaces.IPayeeService;
import com.serviceprovider.business.module.user.model.impl.User;
import com.serviceprovider.business.utility.RequestConstants;
import com.serviceprovider.business.utility.maintenance.settings.RoleUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

//~--- JDK imports ------------------------------------------------------------

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class PayeeController {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    IPayeeService           payeeService;
    @Autowired
    IProfileService         profileService;
    @Autowired
    IRoleService            roleService;
    @Autowired
    IUserService            userService;
    @Autowired
    @Qualifier("validator")
    private Validator       validator;

    private List<Role> getPayeeRoles() {
        List<Role> ret  = new ArrayList<Role>();
        Role       role = roleService.getRoleByName(RoleUtils.ROLE_PAYEE);

        if (role == null) {
            Role newRole = new Role();

            newRole.setActive(true);
            newRole.setComments("This role was not present in empty db, created by application!!");
            newRole.setDescription("Payee role");
            newRole.setName(RoleUtils.ROLE_PAYEE);
            roleService.insertRole(newRole);
            role = roleService.getRoleByName(RoleUtils.ROLE_PAYEE);
            ret.add(role);
        } else {
            ret.add(role);
        }

        return ret;
    }

    @RequestMapping(value = RequestConstants.PayeeRequests.PAYEES)
    public ModelAndView enterPayee() {
        ModelAndView mav = new ModelAndView(RequestConstants.PayeeRequests.VIEW_PAYEES);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.UPDATE_PAYEE,
        method = RequestMethod.GET
    )
    public ModelAndView enterUpdate(HttpServletRequest request) {
        ModelAndView mav     = new ModelAndView(RequestConstants.PayeeRequests.VIEW_UPDATE_PAYEE);
        int          payeeId = Integer.parseInt(request.getParameter("payeeId"));
        Payee        form    = payeeService.getById(payeeId);

        mav.addObject("payee", form);
        mav.addObject("roleList", getPayeeRoles());

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.UPDATE_PAYEE,
        method = RequestMethod.POST
    )
    public ModelAndView update(@ModelAttribute("payee") Payee form, BindingResult result) {
        validator.validate(form, result);

        ModelAndView mav = null;

        if (result.hasErrors()) {
            mav = new ModelAndView(RequestConstants.PayeeRequests.VIEW_UPDATE_PAYEE);
            mav.addObject("roleList", getPayeeRoles());

            return mav;
        }

        form.setPassword(passwordEncoder.encodePassword(form.getPassword(), null));
        payeeService.save(form);
        mav = new ModelAndView("redirect:" + RequestConstants.PayeeRequests.VIEW_PAYEES_VIEW);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.CREATE_PAYEE,
        method = RequestMethod.GET
    )
    public ModelAndView enterCreate(HttpSession sess) {
        ModelAndView mav      = new ModelAndView(RequestConstants.PayeeRequests.VIEW_CREATE_PAYEE);
        Payee        form     = new Payee();
        List<Role>   roleList = getPayeeRoles();

        form.setRole(roleList.get(0));

        UserProfile profile = new UserProfile();

        profile.setFirstName("");
        profile.setLastName("");
        form.setProfile(profile);
        mav.addObject("payee", form);
        mav.addObject("roleList", roleList);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.CREATE_PAYEE,
        method = RequestMethod.POST
    )
    public ModelAndView createPayee(@ModelAttribute("payee") Payee form, BindingResult result) {
        validator.validate(form, result);

        ModelAndView mav = null;

        if (result.hasErrors()) {
            mav = new ModelAndView(RequestConstants.PayeeRequests.CREATE_PAYEE_VIEW);
            mav.addObject("roleList", roleService.findAll());

            return mav;
        }

        List<Payee> payees = payeeService.findAll();

        for (Payee payee : payees) {
            if ((payee.getEmail()).equals(form.getEmail())) {
                mav = new ModelAndView(RequestConstants.PayeeRequests.CREATE_PAYEE_VIEW);
                mav.addObject("roleList", roleService.findAll());
                mav.addObject("emailAddressAlreadyPresent", "This email address is already present");

                return mav;
            }
        }

        // encrypt password
        form.setPassword(passwordEncoder.encodePassword(form.getPassword(), null));
        payeeService.save(form);
        mav = new ModelAndView("redirect:" + RequestConstants.PayeeRequests.VIEW_PAYEES_ACTION);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.UPDATE_PAYEE_PROFILE,
        method = RequestMethod.GET
    )
    public ModelAndView enterUpdateProfile(HttpServletRequest request) {
        ModelAndView mav     = new ModelAndView(RequestConstants.PayeeRequests.VIEW_UPDATE_PAYEE_PROFILE);
        UserProfile  profile = new UserProfile();
        int          payeeId = Integer.parseInt(request.getParameter("payeeId"));
        User         user    = userService.getById(payeeId);

        mav.addObject("payeeProfile", user);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.UPDATE_PAYEE_PROFILE,
        method = RequestMethod.POST
    )
    public ModelAndView updatePayeeProfile(@ModelAttribute("payeeProfile") OldUser form, BindingResult result) {
        validator.validate(form, result);

        ModelAndView mav = null;

        if (result.hasErrors()) {
            mav = new ModelAndView(RequestConstants.PayeeRequests.VIEW_UPDATE_PAYEE_PROFILE);
            mav.addObject("payeeInfo", payeeService.getById(form.getId()));

            return mav;
        }

        // userService.update(form);
        if (form.getProfile() != null) {
            profileService.update(form.getProfile());
        }

        mav = new ModelAndView("redirect:" + RequestConstants.PayeeRequests.VIEW_PAYEES_ACTION);

        return mav;
    }

    @RequestMapping(
        value  = RequestConstants.PayeeRequests.DELETE_PAYEE,
        method = RequestMethod.GET
    )
    public ModelAndView deletePayee(HttpServletRequest request) {
        ModelAndView mav     = new ModelAndView("redirect:" + RequestConstants.PayeeRequests.VIEW_PAYEES_VIEW);
        int          payeeId = Integer.parseInt(request.getParameter("payeeId"));

        payeeService.remove(payeeId);

        return mav;
    }
}



